package com.example.joke.custom.indicator

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import com.example.joke.R
import com.example.joke.custom.indicator.eg.Indicator
import com.example.joke.utils.DensityUtil

/**
 * 线型斜切指示器
 */
class LineIndicator @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), Indicator {

    private var params: RelativeLayout.LayoutParams? = null
    // 指示器选中item画笔
    private var mSelectPaint: Paint
    // 指示器未选中item画笔
    private var mUnselectPaint: Paint

    // 指示器item个数
    var mCount = 0
    // 指示器高度
    var mHeight = 2F
    // 指示器选中item的宽度
    var mSelectWidth = 28F
    // 指示器未选中item的宽度
    var mUnselectWidth = 10F
    // 指示器item斜切的宽度
    var mSpaceWidth = 1F
    // 每个指示器item之间的间距
    var mDistanceBtwItem = 2F
    // 指示器前一个选中的位置
    private var mPrePosition = -1
    // 指示器当前选中的位置
    private var mCurrentPosition = 0
    // 指示器选中item的颜色
    var mSelectColor: Int = Color.WHITE
    // 指示器未选中item的颜色
    var mUnselectColor: Int = Color.parseColor("#99FFFFFF")
    // 缩放倍数: (选中宽度-未选中宽度)/未选中宽度
    var offset = 1.8F
    // 缩放执行时间
    var duration = 500L

    init {
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.LineIndicator,
            defStyleAttr, 0
        ).apply {
            // 读取自定义高度属性
            mHeight = getDimensionPixelSize(
                R.styleable.LineIndicator_custom_height,
                // 默认高度
                DensityUtil.dp2px(context,2f)
            ).toFloat()

            mSelectWidth = getDimensionPixelSize(
                R.styleable.LineIndicator_select_width,
                DensityUtil.dp2px(context,28f)
            ).toFloat()

            mUnselectWidth = getDimensionPixelSize(
                R.styleable.LineIndicator_unselect_width,
                DensityUtil.dp2px(context,10f)
            ).toFloat()

            mDistanceBtwItem = getDimensionPixelSize(
                R.styleable.LineIndicator_distance_btw_item,
                DensityUtil.dp2px(context,2f)
            ).toFloat()

            mSpaceWidth = getDimensionPixelSize(
                R.styleable.LineIndicator_space_width,
                DensityUtil.dp2px(context,1f)
            ).toFloat()

            mSelectColor = getColor(
                R.styleable.LineIndicator_select_color,
                Color.WHITE
            )

            mUnselectColor = getColor(
                R.styleable.LineIndicator_unselect_color,
                Color.parseColor("#99FFFFFF")
            )

            offset = getFloat(
                R.styleable.LineIndicator_offset,
                1.8F
            )

            recycle()
        }

//        layoutParams.height = mHeight.toInt()

        mCount = 5
//        mHeight = DensityUtil.dip2px(2f).toFloat()
//        mSelectWidth = DensityUtil.dip2px(28f).toFloat()
//        mUnselectWidth = DensityUtil.dip2px(10f).toFloat()
//
//        mDistanceBtwItem = DensityUtil.dip2px(2f).toFloat()
//        mSpaceWidth = DensityUtil.dip2px(1f).toFloat()

        mSelectPaint = Paint()
        mSelectPaint.isAntiAlias = true
        mSelectPaint.color = mSelectColor
        mSelectPaint.style = Paint.Style.FILL

        mUnselectPaint = Paint()
        mUnselectPaint.isAntiAlias = true
        mUnselectPaint.color = mUnselectColor
        mSelectPaint.style = Paint.Style.FILL
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(
            (mSelectWidth + (mUnselectWidth + mDistanceBtwItem) * (mCount - 1)).toInt(),
            mHeight.toInt()
        )
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        for (i in 0 until mCount) {

            val path = Path()
            val newSelectWidth = mUnselectWidth * (1 + offset)
            var newUnselectWidth = mSelectWidth - (mUnselectWidth * offset)

            if (i < mCurrentPosition) {
                if (i == 0) {
                    path.lineTo(if (i == mPrePosition) newUnselectWidth else mUnselectWidth, 0F)
                    path.lineTo((if (i == mPrePosition) newUnselectWidth else mUnselectWidth) - mSpaceWidth, mHeight)
                    path.lineTo(0F, mHeight)
                    Log.d("onDraw---", "1".plus("---").plus(i))
                } else {
                    if (i <= mPrePosition) {
                        path.moveTo(((mUnselectWidth + mDistanceBtwItem) * i) + mSpaceWidth, 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * i) + if (i == mPrePosition) newUnselectWidth else mUnselectWidth, 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * i) + (if (i == mPrePosition) newUnselectWidth else mUnselectWidth) - mSpaceWidth, mHeight)
                        path.lineTo((mUnselectWidth + mDistanceBtwItem) * i, mHeight)
                        Log.d("onDraw---", "2".plus("---").plus(i))
                    } else {
                        path.moveTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1)) + newUnselectWidth + mDistanceBtwItem + mSpaceWidth, 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1)) + newUnselectWidth + mDistanceBtwItem + mUnselectWidth, 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1)) + newUnselectWidth + mDistanceBtwItem + mUnselectWidth - mSpaceWidth, mHeight)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1)) + newUnselectWidth + mDistanceBtwItem, mHeight)
                        Log.d("onDraw---", "3".plus("---").plus(i))
                    }
                }
                path.close()
                mUnselectPaint.color = mUnselectColor
                canvas?.drawPath(path, mUnselectPaint)

            } else if (i == mCurrentPosition) {
                if (i == 0) {
                    path.lineTo(if (mPrePosition == mCurrentPosition) mSelectWidth else newSelectWidth, 0F)
                    path.lineTo((if (mPrePosition == mCurrentPosition) mSelectWidth else newSelectWidth) - mSpaceWidth, mHeight)
                    path.lineTo(0F, mHeight)
                    Log.d("onDraw---", "4".plus("---").plus(i))
                } else {
                    if (i == (mCount - 1) || mPrePosition < mCurrentPosition) {
                        path.moveTo((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newUnselectWidth + mDistanceBtwItem + mSpaceWidth, 0F)
                        path.lineTo((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newUnselectWidth + mDistanceBtwItem + newSelectWidth, 0F)
                        path.lineTo((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newUnselectWidth + mDistanceBtwItem + newSelectWidth - if (i == mCount - 1) 0F else mSpaceWidth, mHeight)
                        path.lineTo((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newUnselectWidth + mDistanceBtwItem, mHeight)
                        Log.d("onDraw---", "5".plus("---").plus(i))
                    } else {
                        path.moveTo(((mUnselectWidth + mDistanceBtwItem) * i) + mSpaceWidth, 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * i) + newSelectWidth, 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * i) + newSelectWidth - mSpaceWidth, mHeight)
                        path.lineTo((mUnselectWidth + mDistanceBtwItem) * i, mHeight)
                        Log.d("onDraw---", "6".plus("---").plus(i))
                    }
                }
                path.close()
                mSelectPaint.color = mSelectColor
                canvas?.drawPath(path, mSelectPaint)

            } else {    // i > mCurrentPosition
                if (i == mCount - 1) {
                    if (i == mPrePosition) {
                        path.moveTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem + mSpaceWidth), 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem + newUnselectWidth), 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem + newUnselectWidth), mHeight)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem), mHeight)
                        Log.d("onDraw---", "7".plus("---").plus(i))
                    } else {
                        if (mCount >= 3) {
                            path.moveTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mSpaceWidth), 0F)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mUnselectWidth), 0F)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mUnselectWidth), mHeight)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2), mHeight)
                            Log.d("onDraw---", "8".plus("---").plus(i))
                        } else {
                            path.moveTo((mSelectWidth + mDistanceBtwItem + mSpaceWidth), 0F)
                            path.lineTo((mSelectWidth + mDistanceBtwItem + mUnselectWidth), 0F)
                            path.lineTo((mSelectWidth + mDistanceBtwItem + mUnselectWidth), mHeight)
                            path.lineTo((mSelectWidth + mDistanceBtwItem), mHeight)
                            Log.d("onDraw---", "9".plus("---").plus(i))
                        }
                    }
                } else {    // i != mCount - 1
                    if (mPrePosition < mCurrentPosition) {
                        path.moveTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mSpaceWidth), 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mUnselectWidth), 0F)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mUnselectWidth - mSpaceWidth), mHeight)
                        path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2), mHeight)
                        Log.d("onDraw---", "10".plus("---").plus(i))
                    } else {    // mPrePosition > mCurrentPosition
                        if (i <= mPrePosition) {
                            path.moveTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem + mSpaceWidth), 0F)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem + if (i == mPrePosition) newUnselectWidth else mUnselectWidth), 0F)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem + (if (i == mPrePosition) newUnselectWidth else mUnselectWidth) - mSpaceWidth), mHeight)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 1) + newSelectWidth + mDistanceBtwItem), mHeight)
                            Log.d("onDraw---", "11".plus("---").plus(i))
                        } else {
                            path.moveTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mSpaceWidth), 0F)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mUnselectWidth), 0F)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2 + mUnselectWidth - mSpaceWidth), mHeight)
                            path.lineTo(((mUnselectWidth + mDistanceBtwItem) * (i - 2) + newSelectWidth + newUnselectWidth + mDistanceBtwItem * 2), mHeight)
                            Log.d("onDraw---", "12".plus("---").plus(i))
                        }
                    }
                }
                path.close()
                mUnselectPaint.color = mUnselectColor
                canvas?.drawPath(path, mUnselectPaint)
            }
        }
    }
    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
//        Log.d("onPageScrolled---", position.toString().plus("---").plus(positionOffset))
//        mCurrentPosition = position
//        offset = positionOffset
//        invalidate()
    }

    override fun onPageSelected(position: Int) {
        Log.d("onPageSelected---", position.toString())
        mPrePosition = mCurrentPosition
        mCurrentPosition = position
        Log.d("onPageSelected---width", mSelectWidth.toString().plus("---").plus(mUnselectWidth))

        val animator = ValueAnimator.ofFloat(0F, offset)
        animator.addUpdateListener { animation ->
//            val animatedFraction: Float = animation.animatedValue as Float
//            Log.d("onPageSelected---anim", animatedFraction.toString())

            // 计算新的宽度
//            val newSelectWidth = mUnselectWidth * (1 + animatedFraction)
//            val newUnselectWidth = mSelectWidth - (mUnselectWidth * animatedFraction)
//            Log.d("onPageSelected---widths", animatedFraction.toString().plus("---").plus(newSelectWidth).plus("---").plus(newUnselectWidth))

            offset = animation.animatedValue as Float
            invalidate()
        }


        animator.setDuration(duration)

        animator.start()
    }

    override fun onPageScrollStateChanged(state: Int) {
    }

    override fun initIndicatorCount(pagerCount: Int) {
        mCount = pagerCount
        visibility = if (pagerCount > 1) VISIBLE else GONE

        requestLayout()
    }

    override fun getView(): View {
        return this
    }

    override fun getParams(): RelativeLayout.LayoutParams {
        if (params == null) {
            params = RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            )
            params!!.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
            params!!.addRule(RelativeLayout.CENTER_HORIZONTAL)
            params!!.bottomMargin = 10
        }
        return params as RelativeLayout.LayoutParams
    }
}